// Include Files
#include "Definitions.h"

/////////////////////////////////////////////////////////////////////////////////////
// list_t Templated Implementation

template< typename element_t >
IE::list_t<element_t>::list_t( uint_t _uCapacity ) : 
m_uSize(0), m_uCapacity(_uCapacity)
{
	// create a new list
	m_pData = new element_t[m_uCapacity];
}

template< typename element_t >
IE::list_t<element_t>::list_t( element_t *_pData, uint_t _uCount )
	: m_uSize(_uCount), m_uCapacity(_uCount)
{
	// make sure the parameters are valid
	assert( _pData != CE_NULL );

	// create a new list
	m_pData = new element_t[m_uCapacity];
	for( int_t i = 0; i < m_uSize; ++i )
	{
		m_pData[i] = _pData[i];
	}
}

template< typename element_t >
IE::list_t<element_t>::list_t( list_t<element_t> const & _rList )
 : m_uSize(_rList.m_uSize), m_uCapacity(_rList.m_uCapacity)
{
	if(_rList.m_pData)
	{
		// create a new list
		m_pData = new element_t[m_uCapacity];
		for( uint_t i = 0; i < _rList.m_uSize; ++i )
		{
			m_pData[i] = _rList.m_pData[i];
		}
	}
	else
	{
		// the list to copy is empty
		m_pData = CE_NULL;
	}
}

template< typename element_t >
void IE::list_t<element_t>::Append( element_t & _rElement )
{
	// if the list is out of space, make it bigger
	if( m_uSize == m_uCapacity )
	{
		// increase the capacity
		m_uCapacity *= 2;
		if( m_uCapacity == 0 )
		{
			m_uCapacity = 1;
		}

		// make a new list
		element_t * pOld = m_pData;
		m_pData = new element_t[m_uCapacity];
		for( uint_t i = 0; i < m_uSize; ++i )
		{
			m_pData[i] = pOld[i];
		}
		delete[] pOld;
	}

	// add the element to the list
	m_pData[ m_uSize++ ] = _rElement;
}

template< typename element_t >
void IE::list_t<element_t>::SetCapacity( uint_t _uCapacity )
{
	// save the old list and create a new one
	element_t *pTemp = m_pData;
	m_pData = new element_t[_uCapacity];

	// copy the data into the new list
	uint_t uCopy = m_uSize < _uCapacity ? m_uSize : _uCapacity;
	for( uint_t i = 0; i < uCopy; ++i )
	{
		m_pData[i] = pTemp[i];
	}

	// delete the old list
	delete[] pTemp;
}

template< typename element_t >
void IE::list_t<element_t>::Clear()
{
	// if there is a list, get rid of it
	if(m_pData)
	{
		delete[] m_pData;
		m_pData     = CE_NULL;
		m_uSize     = 0;
		m_uCapacity = 0;
	}
}

template< typename element_t >
IE::list_t<element_t> & IE::list_t<element_t>::operator =( 
	list_t<element_t> const & _rList )
{
	// save the size and capacity
	m_uSize     = _rList.m_uSize;
	m_uCapacity = _rList.m_uCapacity;

	// if there was an old list, delete it
	if(m_pData) delete[] m_pData;

	if(_rList.m_pData)
	{
		// create a new list
		m_pData = new element_t[m_uCapacity];
		for( uint_t i = 0; i < m_uSize; ++i )
		{
			m_pData[i] = _rList.m_pData[i];
		}
	}
	else
	{
		// the list to copy is empty
		m_pData = CE_NULL;
	}

	return *this;
}

/////////////////////////////////////////////////////////////////////////////////////
// flist_t Implementation

template< typename element_t >
IE::flist_t<element_t>::flist_t( uint_t _uCapacity )
 : m_uSize(0), m_uCapacity(_uCapacity)
{
	// create a new list
	m_pData = new element_t[m_uCapacity];
}

template< typename element_t >
IE::flist_t<element_t>::flist_t( element_t *_pData, uint_t _uCount )
 : m_uSize(_uCount), m_uCapacity(_uCount)
{
	// make sure the parameters are valid
	assert( _pData != CE_NULL );

	// create a new list
	m_pData = new element_t[m_uCapacity];
	memcpy( m_pData, _pData, _uCount * sizeof( element_t ) );
}

template< typename element_t >
IE::flist_t<element_t>::flist_t( flist_t<element_t> const &_rList )
 : m_uSize(_rList.m_uSize), m_uCapacity(_rList.m_uCapacity)
{
	if(_rList.m_pData)
	{
		// create a new list
		m_pData = new element_t[m_uCapacity];
		memcpy( m_pData, _rList.m_pData, _rList.m_uSize * sizeof(element_t) );
	}
	else
	{
		// the list to copy is empty
		m_pData = CE_NULL;
	}
}

template< typename element_t >
void IE::flist_t<element_t>::Append( element_t &_rElement )
{
	// if the list is out of space, make it bigger
	if( m_uSize == m_uCapacity )
	{
		// increase the capacity
		m_uCapacity *= 2;
		if( m_uCapacity == 0 )
		{
			m_uCapacity = 1;
		}

		// make a new list
		element_t * pOld = m_pData;
		m_pData = new element_t[m_uCapacity];
		memcpy( m_pData, pOld, m_uSize * sizeof(element_t) );
		delete[] pOld;
	}

	// add the element to the list
	m_pData[ m_uSize++ ] = _rElement;
}

template< typename element_t >
void IE::flist_t<element_t>::SetCapacity( uint_t _uCapacity )
{
	// save the old list and create a new one
	element_t *pTemp = m_pData;
	m_pData = new element_t[_uCapacity];

	// copy the data into the new list
	int_t uCopy = m_uSize < _uCapacity ? m_uSize : _uCapacity;
	memcpy( m_pData, pTemp, uCopy * sizeof(element_t) );

	// delete the old list
	delete[] pTemp;
}

template< typename element_t >
void IE::flist_t<element_t>::Clear()
{
	// if there is a list, get rid of it
	if(m_pData)
	{
		delete[] m_pData;
		m_pData     = NULL;
		m_uSize     = 0;
		m_uCapacity = 0;
	}
}

template< typename element_t >
IE::flist_t<element_t> &IE::flist_t<element_t>::operator =( 
	IE::flist_t<element_t> const & _rList )
{
	// save the size and capacity
	m_uSize     = _rList.m_uSize;
	m_uCapacity = _rList.m_uCapacity;

	// get rid of the old list
	if(m_pData) delete[] m_pData;

	if(_rList.m_pData)
	{
		// create a new list
		m_pData = new element_t[m_uCapacity];
		memcpy( m_pData, _rList.m_pData, m_uSize * sizeof( element_t ) );
	}
	else
	{
		// the list to copy is empty
		m_pData = CE_NULL;
	}

	return *this;
}
